home *** CD-ROM | disk | FTP | other *** search
- /*
- /*
- * (C) 1992 SixxHeads Software
- * (C) 1992 Berkeley Systems Inc.
- *
- * This code is freely distributable, but credit must be given in any
- * derivative work.
- *
- * <Revision History>
- * 05/21/92 smz Created for support of color icon families
- * <release 1.0>
- * 06/16/92 smz need to do a HandToHand with the icon, not detatchresource
- */
-
- #include "Utils.h"
- #include "DrawstringHack.h"
- #include <stdlib.h>
- #include <string.h>
- #include <stddef.h>
- #include <OSUtils.h>
- #include <Memory.h>
-
- /*
- * Special drawstring hacks…
- */
-
- #define cDefaultID 129 // skull wih an 'x' through it!
-
- static FileRecord prefsFile;
- static Boolean theColorQD;
-
- typedef struct SmallFamily {
- short itsID;
- Handle itsicsPHandle;
- Handle itsics4Handle;
- Handle itsics8Handle;
-
- struct SmallFamily **itsNextFamily;
- } SmallFamily, **SmallFamilyHandle;
-
- static SmallFamilyHandle theCachedSmallFamily;
- static SmallFamilyHandle theDefaultSmallFamily;
-
- static SmallFamilyHandle DoLoad(short id)
- {
- reg SmallFamilyHandle hFamily;
- reg SmallFamily *pFamily;
-
- hFamily = (SmallFamilyHandle) NewHandleSys(sizeof(SmallFamily));
- if (hFamily == nil)
- return nil;
-
- HLock(hFamily);
- pFamily = *hFamily;
-
- pFamily->itsID = id;
- pFamily->itsNextFamily = nil;
-
- if ((pFamily->itsicsPHandle = GetResource('ics#', id)) == nil
- || (HandToHand(&pFamily->itsicsPHandle) != noErr)) {
- DisposeHandle(hFamily);
- return nil;
- }
-
- if ((pFamily->itsics4Handle = GetResource('ics4', id)) != nil)
- if (HandToHand(&pFamily->itsics4Handle) != noErr)
- pFamily->itsics4Handle = nil;
-
- if ((pFamily->itsics8Handle = GetResource('ics8', id)) != nil)
- if (HandToHand(&pFamily->itsics8Handle) != noErr)
- pFamily->itsics8Handle = nil;
-
- HUnlock(hFamily);
-
- return hFamily;
- }
-
- Boolean InitPrefsFile()
- {
- SysEnvRec environment; // machine configuration.
-
- NewFileRecord("\pFinderMenu Prefs", 'fmci', 'FMPR', &prefsFile);
- (void) OpenPrefsFile(&prefsFile);
- ClosePrefsFile(&prefsFile);
-
- theCachedSmallFamily = nil;
- theDefaultSmallFamily = DoLoad(cDefaultID);
-
- // find out what kind of machine this is.
- SysEnvirons(curSysEnvVers, &environment);
- theColorQD = (environment.hasColorQD);
-
- return theDefaultSmallFamily != nil;
- }
-
- static void TrashCachedFamily()
- {
- reg SmallFamilyHandle aFamily = theCachedSmallFamily;
-
- while (aFamily != nil) {
- reg SmallFamily *pFamily = *aFamily;
- reg SmallFamilyHandle nextFamily = pFamily->itsNextFamily;
-
- if (pFamily->itsicsPHandle)
- DisposeHandle(pFamily->itsicsPHandle);
- if (pFamily->itsics4Handle)
- DisposeHandle(pFamily->itsics4Handle);
- if (pFamily->itsics8Handle)
- DisposeHandle(pFamily->itsics8Handle);
-
- DisposeHandle(aFamily);
- aFamily = nextFamily;
- }
- theCachedSmallFamily = nil;
- }
-
- static SmallFamilyHandle LoadSmallFamily(short id)
- {
- reg SmallFamilyHandle hFamily;
-
- if (! OpenPrefsFile(&prefsFile))
- return nil;
-
- hFamily = DoLoad(id);
-
- if (! ClosePrefsFile(&prefsFile)) {
- #ifdef DEBUG
- DebugStr("\pcouldn't close prefs!");
- #endif
- }
-
- return hFamily;
- }
-
- static SmallFamilyHandle GetSmallFamily(short id)
- {
- reg SmallFamilyHandle aFamily;
-
- if (PrefsFileChanged(&prefsFile))
- TrashCachedFamily();
-
- aFamily = theCachedSmallFamily;
-
- while (aFamily != nil) {
- reg SmallFamily *pFamily = *aFamily;
- if (pFamily->itsID == id)
- return aFamily;
- aFamily = pFamily->itsNextFamily;
- }
-
- // didn't find it, load it and cache it
- aFamily = LoadSmallFamily(id);
-
- if (aFamily != nil) {
- (**aFamily).itsNextFamily = theCachedSmallFamily;
- theCachedSmallFamily = aFamily;
- }
-
- return aFamily;
- }
-
- static void GetSmallRect(Rect *aRect, Point loc)
- {
- SetRect(aRect, 0, 0, 16, 16);
- OffsetRect(aRect, loc.h, loc.v - 12);
- }
-
- static void DrawBWIcon(SmallFamilyHandle aFamily, Point loc)
- {
- BitMap source;
- Handle icon = (**aFamily).itsicsPHandle;
- GrafPtr curPort;
- Rect dstRect;
-
- if (icon == nil) {
- aFamily = theDefaultSmallFamily;
- icon = (**aFamily).itsicsPHandle;
- if (icon == nil)
- return; // bad news!
- }
-
- GetPort(&curPort);
-
- HLock(icon);
-
- // prepare the source and destination bitmaps.
- source.baseAddr = *icon + 32; // mask address.
- source.rowBytes = 2;
- SetRect(&source.bounds, 0, 0, 16, 16);
-
- GetSmallRect(&dstRect, loc);
-
- // transfer the mask.
- CopyBits(&source, &curPort->portBits, &source.bounds, &dstRect, srcBic, nil);
-
- // and the icon.
- source.baseAddr = *icon;
- CopyBits(&source, &curPort->portBits, &source.bounds, &dstRect, srcOr, nil);
-
- HUnlock(icon);
- }
-
- static void DrawColorIcon(SmallFamilyHandle aFamily, Point loc, short desiredDepth)
- {
- Handle mask, icon;
- CTabHandle clut;
- PixMapHandle source;
- BitMap maskBits;
- long rowBytes;
- Rect dstRect, bounds;
- CGrafPtr curPort; // the current port we created.
- short depthUsed;
- RGBColor saveFore, saveBack;
- RGBColor aColor;
-
- if ((**aFamily).itsics4Handle == nil && (**aFamily).itsics8Handle == nil) {
- if ((**aFamily).itsicsPHandle != nil)
- DrawBWIcon(aFamily, loc);
-
- return;
- }
-
- GetPort(&curPort);
- SetRect(&bounds, 0, 0, 16, 16);
- GetSmallRect(&dstRect, loc);
-
- saveFore = curPort->rgbFgColor;
- saveBack = curPort->rgbBkColor;
- aColor.red = 0;
- aColor.green = 0;
- aColor.blue = 0;
- RGBForeColor(&aColor);
- aColor.red = -1;
- aColor.green = -1;
- aColor.blue = -1;
- RGBBackColor(&aColor);
-
- mask = (**aFamily).itsicsPHandle;
- if (mask) {
- HLock(mask);
- maskBits.baseAddr = *mask + 32;
- maskBits.rowBytes = 2;
- maskBits.bounds = bounds;
- }
-
- if (desiredDepth == 4) {
- icon = (**aFamily).itsics4Handle;
- depthUsed = 4;
- } else {
- icon = (**aFamily).itsics8Handle;
- depthUsed = 8;
- }
-
- if (icon == nil) {
- if (desiredDepth == 4) {
- icon = (**aFamily).itsics8Handle;
- depthUsed = 8;
- } else {
- icon = (**aFamily).itsics4Handle;
- depthUsed = 4;
- }
- }
-
- if (icon == nil) // should never happen
- goto exit;
-
- HLock(icon);
-
- // get color stuff
- clut = GetCTable(depthUsed); // can return nil!
-
- // create a pixmap to stick the icon bits into for screen blitting.
- source = NewPixMap();
- if (! source)
- goto exit;
-
- if (depthUsed == 8)
- rowBytes = 16;
- else
- rowBytes = 8;
-
- (**source).baseAddr = *icon;
- (**source).rowBytes = ((short) rowBytes) | 0x8000;
- (**source).bounds = bounds;
- (**source).pixelType = 0; // chunky model.
- (**source).pixelSize = depthUsed;
- (**source).cmpCount = 1; // if in 32 bit mode this will be 3, so must change.
- (**source).cmpSize = depthUsed; // only chunky images used.
- DisposCTable((**source).pmTable); // dispose of default, uninitialized table.
- (**source).pmTable = clut;
-
- // draw the actual color icon.
- HLock((Handle) source);
- CopyMask((BitMap*) *source, &maskBits, (BitMap*)&curPort->portPixMap, &bounds, &bounds, &dstRect);
- HUnlock((Handle) source);
-
- // release everything we've allocated.
- // note that we dispose these elsewhere, so we don't want DisposPixMap to do it for us
- (**source).pmTable = nil;
- (**source).baseAddr = nil;
- DisposPixMap(source);
-
- exit: // release the icon and clut.
- RGBForeColor(&saveFore);
- RGBBackColor(&saveBack);
-
- if (clut)
- DisposCTable(clut);
-
- if (icon)
- HUnlock(icon);
-
- if (mask)
- HUnlock(mask);
- }
-
- static void TryPlotFamily(SmallFamilyHandle aFamily, Point loc)
- {
- short depth;
- short rowBytes;
-
- if (theColorQD) {
- depth = (**(**GetMainDevice()).gdPMap).pixelSize;
- if (depth < 4)
- depth = 1;
- else if (depth > 8)
- depth = 8;
- } else
- depth = 1;
-
- if (depth == 1)
- DrawBWIcon(aFamily, loc);
- else
- DrawColorIcon(aFamily, loc, depth);
- }
-
- static char *ScanFor(reg char c, reg char *p, reg short len)
- {
- while (len--)
- if (*p == c)
- return p;
- else
- ++p;
-
- return nil;
- }
-
- static short GetStringParm(Str255 s, reg short ixToken)
- {
- Str255 tmp;
- reg char *p = (char *) &s[1];
- reg char *pEnd = p + s[0];
-
- tmp[0] = 0;
-
- // finds tokens in a:
- // CODE(x, y, ...) manner
-
- p = ScanFor('(', p, pEnd - p);
-
- if (p == nil)
- return 0;
-
- ++p;
-
- while (ixToken-- && p <= pEnd) {
- p = ScanFor(',', p, pEnd - p);
-
- if (p == nil)
- return 0;
-
- ++p;
- }
-
- if (p <= pEnd) {
- while (p <= pEnd) {
- if (*p != ' ' && *p != '\t')
- if (*p == ',' || *p == ')')
- break;
- else
- pushchar(*p, tmp);
- ++p;
- }
- return String2Short(tmp);
- }
- return 0;
- }
-
-
- Boolean IsSpecialString(Str255 s)
- {
- return 'IFAM' == (long) (((long) s[1] << 24) | (long) ((long)s[2] << 16) | (long) ((long)s[3] << 8) | (long) s[4]);
- }
-
- void DrawSpecialString(Str255 s)
- {
- Point pnLoc;
- reg SmallFamilyHandle hFam;
-
- GetPen(&pnLoc);
-
- hFam = GetSmallFamily(GetStringParm(s, 0));
-
- if (hFam == nil)
- hFam = theDefaultSmallFamily;
-
- TryPlotFamily(hFam, pnLoc);
- }
-
- short SpecialStringWidth(Str255 s)
- {
- return 16; // width of a SICN
- }
-